package com.liu.yubi.manager;

import com.liu.yubi.common.ErrorCode;
import com.liu.yubi.exception.BusinessException;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author lqh
 * @since 2025-05-31 18:58
 * 什么是Manager？专门为RedisLimiter提供限流基础服务的（提供了一个通用的能力，可以放到任何一个项目中）
 */
@Service
public class RedisLimiterManager {

    @Resource
    private RedissonClient redissonClient;

    /**
     * 限流操作
     * @param key 区分不同的限流器，比如不同的用户id应该分别计算
     */
    public void doRateLimiter(String key){
        /**
         * 新建一个限流器，key作为限流器的唯一标识
         */
        RRateLimiter rateLimiter = redissonClient.getRateLimiter (key);
        /**
         * RateType.OVERALL：全局限流，所有服务器共享同一个限制（如整个集群每秒1次） PER_CLIENT:每台机器独立限流（如每台机器每秒1次，3台机器总共3次）
         * rate：1s生成一个令牌
         * rateInterval：令牌桶的容量，这个设置最多可以存1个令牌
         */
        rateLimiter.trySetRate (RateType.OVERALL,1,1, RateIntervalUnit.SECONDS);
        /**
         * 尝试从令牌桶中获取一个令牌
         */
        boolean b = rateLimiter.tryAcquire (1);
        if (!b){
            throw new BusinessException (ErrorCode.TOO_MANY_REQUEST);
        }
    }
}
